
/**
 * @Title: AdminServiceImpl.java
 * @Package: com.aft.cdcb.modules.admin.service.impl
 * @Description: TODO
 * @author Mandarava
 * @date 2016年8月20日 下午5:55:39
 * @version 1.3.1
 * @Email wuyan1688@qq.com
 */

package com.infoland.modules.main.service.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.infoland.app.Constants;
import com.infoland.common.security.ShiroExt;
import com.infoland.common.security.ShiroUtils;
import com.infoland.common.util.DateUtil;
import com.infoland.common.util.RequestUtil;
import com.infoland.modules.basic.Message;
import com.infoland.modules.basic.SystemConfiguration;
import com.infoland.modules.main.controller.AdminController;
import com.infoland.modules.main.controller.PermissionController;
import com.infoland.modules.main.controller.RoleController;
import com.infoland.modules.main.model.Admin;
import com.infoland.modules.main.model.AdminLog;
import com.infoland.modules.main.model.Icon;
import com.infoland.modules.main.model.Menu;
import com.infoland.modules.main.model.Permission;
import com.infoland.modules.main.model.Role;
import com.infoland.modules.main.service.SystemService;
import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

/**
 * 后台管理服务层
 *
 * @author Mandarava
 * @date 2016年8月20日 下午5:55:39
 * @version V1.3.1
 */

public class SystemServiceImpl implements SystemService {

    /**
     * @param controller
     * @return
     */

    @Override
    public Message login(Controller controller) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        String loginName = controller.getPara("username").trim();
        String password = controller.getPara("password").trim();
        Subject subject = SecurityUtils.getSubject();
        Admin admin = Admin.dao.getAdminByName(loginName);
        UsernamePasswordToken token = new UsernamePasswordToken(loginName, DigestUtils.md5Hex(password));
        try {
            subject.login(token);
        } catch (UnknownAccountException ue) {
            token.clear();
            message.setMessage("登录失败，您输入的账号不存在");
            message.setSuccess(Boolean.FALSE);
        } catch (IncorrectCredentialsException ie) {
            token.clear();
            message.setSuccess(Boolean.FALSE);
            if (Boolean.getBoolean(SystemConfiguration.getMap().get("is_login_failure_lock"))) {
                int loginFailureCount = admin.getAFaildNum() + 1;
                int loginFailureLockCount = Integer
                        .parseInt(SystemConfiguration.getMap().get("login_failure_lock_count"));
                if (loginFailureCount >= loginFailureLockCount) {
                    admin.setAStatus("1");
                    admin.setAStatusV("锁定");
                    admin.setALockedTime(DateUtil.date());
                }
                admin.setAFaildNum(loginFailureCount);
                admin.update();
                if (loginFailureLockCount - loginFailureCount <= 3) {
                    message.setMessage("若连续" + loginFailureLockCount + "次密码输入错误,您的账号将被锁定,您还有"
                            + (loginFailureLockCount - admin.getAFaildNum()) + " 次机会。");
                } else {
                    message.setMessage("登录失败，您的密码不正确");
                }
            } else {
                message.setMessage("登录失败，您的密码不正确");
            }
        } catch (LockedAccountException re) {
            token.clear();
            message.setMessage("登录失败，您的账号已被锁定");
            message.setSuccess(Boolean.FALSE);
        } catch (AccountException e) {
            message.setMessage("登录失败，您的账号已被注销");
            message.setSuccess(Boolean.FALSE);
        }
        if (message.isSuccess()) {
            admin.setAFaildNum(0);
            admin.setALoginNum(admin.getALoginNum() + 1);
            admin.setALoginLastIp(RequestUtil.ip(controller.getRequest()));
            admin.setALoginLastTime(DateUtil.date());
            admin.update();
        }
        return message;
    }

    /**
     * 退出登陆
     *
     */

    @Override
    public void logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
    }

    /**
     * Description
     *
     * @param userName
     * @return
     */

    @Override
    public Admin findAdminByName(String userName) {
        return Admin.dao.getAdminByName(userName);
    }

    /**
     * Description
     *
     * @param admin
     * @return
     */

    @Override
    public List<String> getAdminRoles(Admin admin) {
        return admin.getAdminRolesMark();
    }

    /**
     * Description
     *
     * @param admin
     * @return
     */

    @Override
    public List<String> getAdminPermissions(Admin admin) {
        return admin.getAdminAuthorities();
    }

    /**
     * Description
     *
     * @return
     */

    @Override
    public List<Menu> getAdminResouce() {
        Admin user = ShiroUtils.getLoginAdmin();
        return Admin.dao.getAdminMenus(user.getId());
    }

    /**
     *
     * @param controller
     * @return
     */
    @Override
    public Page<Admin> findAdminByPage(AdminController controller) {
        JSONObject model = controller.getJSONObject("admin");
        Integer pageNumber = controller.getJSONParaToInt("pageNumber", 1);
        Integer pageSize = controller.getJSONParaToInt("pageSize", 15);
        Page<Admin> page = Admin.dao.findAdminByPage(pageNumber, pageSize, model.getString("user_name"),
                model.getString("login_name"), model.getString("start_time"),model.getString("end_time"),model.getString("login_ip"));
        return page;
    }

    /**
     *
     * @param ids
     * @return
     */
    @Override
    public Message deleteAdmin(JSONArray ids) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        if (null == ids) {
            message.setSuccess(Boolean.FALSE);
            message.setMessage("系统异常。无法执行删除");
            return message;
        }
        int i = Admin.dao.batchDelete(ids);
        if (i > 0) {
            message.setMessage("删除成功，共删除 " + i + " 条用户信息");
        }
        return message;
    }

    @Override
    public Admin findOneAdmin(Long id) {
        return Admin.dao.findOneAdmin(id);
    }

    /**
     *
     * @param roleIds
     * @param admin
     * @return
     */
    @Override
    @Before(Tx.class)
    public Message saveAdmin(JSONArray roleIds, Admin admin) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        if (admin != null && roleIds != null) {
            if (Admin.dao.isExistsAdmin(admin.getALoginName())) {
                message.setSuccess(Boolean.FALSE);
                message.setMessage("该登录名已被占用，不可添加");
            } else {
                admin.setCreateDate(DateUtil.date());
                admin.setALoginPassword(DigestUtils.md5Hex(admin.getALoginPassword()));
                Boolean isSuccess = admin.saveAdmin(roleIds);
                if (isSuccess) {
                    message.setMessage("保存成功");
                } else {
                    message.setMessage("保存失败");
                    message.setSuccess(Boolean.FALSE);
                }
            }
        } else {
            message.setMessage("保存失败，获取参数异常");
            message.setSuccess(Boolean.FALSE);
        }

        return message;
    }

    /**
     *
     * @param id
     * @return
     */
    @Override
    public Message resumedAdmin(Long id) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        Admin admin = findOneAdmin(id);
        if (admin != null) {
            if ("0".equals(admin.getAStatus())) {
                message.setSuccess(Boolean.FALSE);
                message.setMessage("当前用户状态为可用状态，无需恢复");
            } else {
                admin.setAStatus("0");
                admin.setAStatusV("可用");
                admin.setAFaildNum(0);
                admin.setALockedTime(null);
                admin.setModifyDate(DateUtil.date());
                if (admin.update()) {
                    message.setMessage("用户初始化成功！可以正常使用");
                } else {
                    message.setSuccess(Boolean.FALSE);
                    message.setMessage("恢复未能成功，执行修改时异常。");
                }
            }
        } else {
            message.setSuccess(Boolean.FALSE);
            message.setMessage("恢复失败，未能获取参数");
        }
        return message;
    }

    /**
     *
     * @param admin
     * @param roleIds
     * @return
     */
    @Override
    @Before(Tx.class)
    public Message updateAdmin(Admin admin, JSONArray roleIds) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        if (admin != null && admin.getId() != null) {
            admin.setALoginPassword(DigestUtils.md5Hex(admin.getALoginPassword()));
            admin.setModifyDate(DateUtil.date());
            if (admin.updated(roleIds)) {
                message.setMessage("更新成功");
            } else {
                message.setSuccess(Boolean.FALSE);
                message.setMessage("更新未能成功，执行修改时异常。");
            }
        } else {
            message.setSuccess(Boolean.FALSE);
            message.setMessage("更新失败，未能获取参数");
        }
        return message;
    }

    /**
     *
     * @param id
     * @return
     */
    @Override
    public Message writtenOffAdmin(Long id) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        if (id != null) {
            Admin admin = findOneAdmin(id);
            admin.setAStatus("3");
            admin.setAStatusV("注销");
            admin.setModifyDate(DateUtil.date());
            if (admin.update()) {
                message.setMessage("注销成功，该用户当前不可用");
            } else {
                message.setSuccess(Boolean.FALSE);
                message.setMessage("更新注销成功，执行修改时异常。");
            }
        } else {
            message.setSuccess(Boolean.FALSE);
            message.setMessage("注销失败，未能获取参数");
        }
        return message;
    }

    /**
     *
     * @return
     */
    @Override
    public List<Role> findRole() {
        ShiroExt shiro = new ShiroExt();
        if (shiro.hasAnyRole(Constants.SUPER_MANAGER_ROLE)) {
            return Role.dao.findRole();
        } else {
            return Role.dao.findNotSystemRole();
        }
    }


    /**
     *
     * @param ids
     * @return
     */
    @Override
    @Before(Tx.class)
    public Message batchDelRole(Integer[] ids) {
        Integer result = 0;
        Message message = new Message();
        String[] exitisNames = Role.dao.existsAdminName(ids);

        if (StrKit.notBlank(exitisNames)) {
            message.setMessage("角色：【" + exitisNames[1] + "】 下已存在用户：【" + exitisNames[0] + "】，无法删除。");
        } else {
            // 删除角色与菜单对应关系
            result = Role.dao.delRoleAndMenusRelation(ids);
            // 删除角色与功能权限对应关系
            result += Role.dao.delRoleAndFunRelation(ids);
            // 删除角色信息
            result += Role.dao.delRoles(ids);
            if (result > 0) {
                message.setSuccess(Boolean.TRUE);
                message.setMessage("删除成功");
            } else {
                message.setMessage("删除失败");
            }
        }
        return message;
    }

    /**
     *
     * @param id
     * @return
     */
    @Override
    public Role findOneRole(Long id) {
        return Role.dao.findById(id);
    }

    /**
     *
     * @param controller
     * @return
     */
    @Override
    public Page<Role> findRoleByPage(RoleController controller) {
        Integer pageNumber = controller.getJSONParaToInt("pageNumber", 1);
        Integer pageSize = controller.getJSONParaToInt("pageSize", 15);
        String rName = controller.getJSONPara("r_name");
        String rValue = controller.getJSONPara("r_value");
        Boolean isAdmin = Boolean.FALSE;
        ShiroExt shiro = new ShiroExt();
        if (shiro.hasAnyRole(Constants.SUPER_MANAGER_ROLE)) {
            isAdmin = Boolean.TRUE;
        }
        return Role.dao.findRoleByPage(pageNumber, pageSize, rName, rValue, isAdmin);
    }

    /**
     *
     * @param role
     * @return
     */
    @Override
    public Message saveRole(Role role) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        if (role != null) {
            role.setCreateDate(DateUtil.date());
            Boolean isSuccess = role.save();
            if (isSuccess) {
                message.setMessage("保存成功");
            } else {
                message.setMessage("保存失败");
                message.setSuccess(Boolean.FALSE);
            }
        } else {
            message.setMessage("保存失败，获取参数异常");
            message.setSuccess(Boolean.FALSE);
        }

        return message;
    }

    /**
     *
     * @param role
     * @return
     */
    @Override
    public Message updateRole(Role role) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        if (role != null && role.getId() != null) {
            role.setModifyDate(DateUtil.date());
            if (role.update()) {
                message.setMessage("更新成功");
            } else {
                message.setSuccess(Boolean.FALSE);
                message.setMessage("更新未能成功，执行修改时异常。");
            }
        } else {
            message.setSuccess(Boolean.FALSE);
            message.setMessage("更新失败，未能获取参数");
        }
        return message;
    }

    /**
     *
     * @return
     */
    @Override
    public List<Menu> finAllMenus() {
        return Menu.dao.findAllMenus();
    }

    /**
     *
     * @param id
     * @return
     */
    @Override
    public Message deleteMenu(Integer id) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        if (id != null) {
            Menu menu = findOneMenu(id);
            if (menu.hasChildren()) {
                message.setSuccess(Boolean.FALSE);
                message.setMessage(menu.getMName() + "下存在子菜单，无法删除！");
                return message;
            }
            if (menu.hasRole()) {
                message.setSuccess(Boolean.FALSE);
                message.setMessage(menu.getMName() + "已和角色建立关联关系，无法删除！");
                return message;
            }
            if (menu.hasPermission()) {
                message.setSuccess(Boolean.FALSE);
                message.setMessage(menu.getMName() + "存在操作权限，无法删除！");
                return message;
            }
            if (menu.delete()) {
                message.setMessage("删除成功");
            } else {
                message.setSuccess(Boolean.FALSE);
                message.setMessage("删除未能成功，执行删除时异常。");
            }
        } else {
            message.setSuccess(Boolean.FALSE);
            message.setMessage("更新失败，未能获取参数");
        }
        return message;
    }

    /**
     *
     * @param id
     * @return
     */
    @Override
    public Menu findOneMenu(Integer id) {
        return Menu.dao.findById(id);
    }

    /**
     *
     * @param menus
     * @return
     */
    @Override
    public Message saveMenu(Menu menus) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        // 若菜单不为空，进行操作
        if (menus != null) {
        	// 设置创建时间为当前时间
            menus.setCreateDate(DateUtil.date());
            // 设置ideas初始为1
            menus.setMIdeas("1");
            // 返回保存成功与否的信息
            Boolean isSuccess = menus.save();
            // 如果保存成功，设置idea和parentid
            if (isSuccess) {
            	if(menus.getMParentId() != null){
            		menus.setMIdeas(new StringBuilder().append(menus.getId()).append(",").append(menus.getMParentId()).toString());
            	}else{
            		menus.setMIdeas(menus.getId().toString());
            	}
            	menus.update();
                message.setMessage("保存成功");
            } else {
                message.setMessage("保存失败");
                message.setSuccess(Boolean.FALSE);
            }
        } else {
            message.setMessage("保存失败，获取参数异常");
            message.setSuccess(Boolean.FALSE);
        }

        return message;
    }

    /**
     *
     * @param menus
     * @return
     */
    @Override
    public Message updateMenu(Menu menus) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        if (menus != null && menus.getId() != null) {
            menus.setModifyDate(DateUtil.date());
            if (menus.update()) {
                message.setMessage("更新成功");
            } else {
                message.setSuccess(Boolean.FALSE);
                message.setMessage("更新未能成功，执行修改时异常。");
            }
        } else {
            message.setSuccess(Boolean.FALSE);
            message.setMessage("更新失败，未能获取参数");
        }
        return message;
    }

    /**
     *
     * @param modelList
     * @return
     */
    @Override
    public Message batchSavePermission(List<Permission> modelList) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        if (modelList != null && modelList.size() > 0) {
            for (Permission permission : modelList) {
                permission.setCreateDate(DateUtil.date());
            }
            if (Permission.dao.batchSavePermission(modelList)) {
                message.setMessage("保存成功");
            } else {
                message.setSuccess(Boolean.FALSE);
                message.setMessage("保存未能成功，执行插入时异常。");
            }
        } else {
            message.setSuccess(Boolean.FALSE);
            message.setMessage("保存失败，未能获取参数");
        }
        return message;
    }

    /**
     *
     * @param id
     * @return
     */
    @Override
    public Message deletePermission(Long id) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        if (id != null) {
            Permission permission = findOnePermission(id);
            if (permission.roleHasPermission()) {
                message.setSuccess(Boolean.FALSE);
                message.setMessage(permission.getPName() + "已和角色建立关联关系，无法删除！");
            } else {
                if (permission.delete()) {
                    message.setMessage("删除成功");
                } else {
                    message.setSuccess(Boolean.FALSE);
                    message.setMessage("删除失败");
                }
            }
        } else {
            message.setSuccess(Boolean.FALSE);
            message.setMessage("删除失败，未能获取参数");
        }
        return message;
    }

    /**
     *
     * @param id
     * @return
     */
    @Override
    public Permission findOnePermission(Long id) {
        return Permission.dao.findById(id);
    }

    /**
     *
     * @param controller
     * @return
     */
    @Override
    public Page<Permission> findPermissionByPage(PermissionController controller) {
        Integer pageNumber = controller.getJSONParaToInt("pageNumber", 1);
        Integer pageSize = controller.getJSONParaToInt("pageSize", 15);
        String pName = controller.getJSONPara("p_name");
        String pValue = controller.getJSONPara("p_value");
        String pPath = controller.getJSONPara("p_path");
        return Permission.dao.findPerissionByPage(pageNumber, pageSize, pName,pValue,pPath);
    }

    /**
     *
     * @param model
     * @return
     */
    @Override
    public Message updatePermission(Permission model) {
        Message message = new Message();
        message.setSuccess(Boolean.TRUE);
        if (model != null && model.getId() != null) {
            model.setModifyDate(DateUtil.date());
            if (model.update()) {
                message.setMessage("更新成功");
            } else {
                message.setSuccess(Boolean.FALSE);
                message.setMessage("更新未能成功，执行修改时异常。");
            }
        } else {
            message.setSuccess(Boolean.FALSE);
            message.setMessage("更新失败，未能获取参数");
        }
        return message;
    }

    /**
     *
     * @return
     */
    @Override
    public List<Menu> authorityList() {
        return Menu.dao.findLowestMenus();
    }

	/**
	 * 为角色授权
	 * 
	 * @author lixp           
	 * @param roleId            角色id
	 * @param menuIds			选择的菜单
	 * @param permissionIds		选择的权限
	 * @return					授权成功与否的信息
	 */
    @Override
    @Before(Tx.class)
    public Message authority(Long roleId, JSONArray menuIds, JSONArray permissionIds) {
    	// 初始设置message存放信息
		Message message = new Message();
		message.setSuccess(Boolean.TRUE);
		// 如果选择的菜单不为null且长度大于0，角色id不为null,执行操作
		if ((menuIds != null && menuIds.size() > 0) && roleId != null) {
			// 移除角色id对应的之前的所有权限和菜单
			Menu.dao.removeRoleAndMenusMapping(roleId);
			Permission.dao.removeRoleAndPermissionMapping(roleId);
			// 定义set集合，存放菜单
			Set<String> unique = new HashSet<String>();
			// 遍历菜单数组
			for (Object menus : menuIds) {
				// 将菜单数组中项转换为String ,用于截取逗号
				String menu = menus.toString();
				String[] menusIds = menu.split(",");
				// 将截取完毕的项放入set集合中
				for (String id : menusIds) {
					unique.add(id);
				}
			}
			// 将菜单数组转换为String数组  此处为copy,
			String[] uniqueMenuIds = unique.toArray(new String[unique.size()]);
			// 设置角色对应所选择的菜单
			Menu.dao.setRoleAndMenusMapping(uniqueMenuIds, roleId);
			// 如果权限数组不为null且长度大于0，设置角色所选择的权限
			if (permissionIds != null && permissionIds.size() > 0)
				Permission.dao.setRoleAndPermissionMapping(permissionIds, roleId);
			message.setSuccess(Boolean.TRUE);
			message.setMessage("授权成功");
			return message;
		} else {
			message.setSuccess(Boolean.FALSE);
			message.setMessage("授权失败，未能获取参数");
		}
		return message;
    }

    @Override
    public List<Menu> findMens() {
        return Menu.dao.findMenus();
    }

    @Override
    public List<Record> menusRoleList(Long roleId) {
        return Menu.dao.menusRoleList(roleId);
    }

    @Override
    public List<Record> permissionRoleList(Integer roleId) {
        return Permission.dao.permissionRoleList(roleId);
    }

    @Override
    public Message saveAdminLog(AdminLog al) {
        Message m = new Message();
        m.setSuccess(Boolean.FALSE);
        boolean b = false;
        try {
            b = al.save();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (b) {
            m.setSuccess(Boolean.TRUE);
            m.setMessage("保存日志成功");
        } else
            m.setMessage("管理员操作日志保存失败");

        return m;
    }

    @Override
    public List<Role> findAllRole() {
        return Role.dao.findRole();
    }
	/**
	 * 增加权限数据
	 * @author lixp
	 * @param model   permission对象
	 * @return        储存成功与否的信息
	 */
	@Override
	public Message savePermission(Permission model) {
		Message message = new Message();
		message.setSuccess(Boolean.TRUE);
		if (model != null ) {
			model.setCreateDate(DateUtil.date());
			if (model.save()) {
				message.setMessage("保存成功");
			} else {
				message.setSuccess(Boolean.FALSE);
				message.setMessage("保存未能成功，执行修改时异常。");
			}
		} else {
			message.setSuccess(Boolean.FALSE);
			message.setMessage("保存失败，未能获取参数");
		}
		return message;
	}
	
	/**
	 * @author lixp
	 * 查询所有图标
	 * @return
	 */
	@Override
	public List<Icon> findIcon() {
		return Icon.dao.findIcon();
	}
	
	/**
	 * 根据菜单id获取权限列表
	 * @author lixp
	 * @param menuId  菜单id
	 * @return        权限列表
	 */
	@Override
	public List<Permission> permissionMenuList(Long menuId){
		return Permission.dao.findByMenuIdOnMenuFun(menuId);
	}
}
